#-*- coding: utf8 -*-
'''
String validators
-----------------

The basic validator for string objects is the Str() schema. It checks if an 
object is an string and, optionally, if it has a maximum length or a given
encoding.

>>> schema = Str(); schema.isvalid('foo')
True
>>> schema = Str(maxlength=2); schema.isvalid('foo')
False
>>> schema = Str(encoding='ascii'); schema.isvalid('fôo')
False

All other validators in this module accept at least these parameters. 
'''
from __future__ import absolute_import, print_function, unicode_literals, division
from future_builtins import * #@UnusedWildImport
if __name__ == '__main__':
    __package__ = b'pyson.schema' #@ReservedAssignment
    import pyson.schema #@UnusedImport

import re
from ..types import String
from .schema_class import Schema
from .util import get_schemas

class Str(Schema):
    '''
    Checks if object is a string
    '''

    def __init__(self, *args, **kwds):
        self.encoding = kwds.pop('encoding', None)
        self.maxlength = kwds.pop('maxlength', None)
        super(Str, self).__init__(*args, **kwds)

    def isvalid(self, obj, **kwds):
        if isinstance(obj, String):
            if self.encoding is not None:
                try:
                    obj.decode(self.encoding)
                except UnicodeDecodeError:
                    return False

            if self.maxlength is not None:
                return len(obj) <= self.maxlength

            return True
        else:
            return False

#    def adapt(self, obj, inplace=False, path=[]):
#        try:
#            return unicode(u'' + obj)
#        except TypeError:
#            raise errors.AdaptationError((None, path))

class Regex(Str):
    '''
    Checks if a string is valid if it matches a given regex expression. 
    '''
    def __init__(self, regex, *args, **kwds):
        if isinstance(regex, basestring):
            self.regex = re.compile(regex)
        else:
            self.regex = regex
        super(Regex, self).__init__(*args, **kwds)

    def isvalid(self, obj, **kwds):
        if super(Regex, self).isvalid(obj):
            return self.regex.match(obj) is not None
        else:
            return False

class Email(Regex):
    '''
    Validates well-formed e-mail strings.
    '''

    EMAIL_REGEX = re.compile('^[a-zA-Z0-9+_\-\.]+@[0-9a-zA-Z][.-0-9a-zA-Z]*.[a-zA-Z]+$')
    def __init__(self, *args, **kwds):
        super(Email, self).__init__(self.EMAIL_REGEX, *args, **kwds)

class Lang(Regex):
    '''
    Validates well-formed language code strings (e.g., pt-BR, en-US, en, etc).
    '''

    lang_re = re.compile('^[a-z][a-z](-[a-z][a-z])?$')
    def __init__(self, *args, **kwds):
        super(Lang, self).__init__(self.lang_re, *args, **kwds)


__all__ = get_schemas(globals())
if __name__ == '__main__':
    import doctest
    doctest.testmod(optionflags=doctest.REPORT_ONLY_FIRST_FAILURE, verbose=0)
